package com.xinhe.web.service;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.xinhe.web.common.BusinessException;
import com.xinhe.web.common.Result;
import com.xinhe.web.entity.*;
import com.xinhe.web.reposity.BankCardRepository;
import com.xinhe.web.response.MemberView;
import com.xinhe.web.session.UserSessionManager;
import com.xinhe.web.util.CheckBankCard;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service

public class BankCardService {

    @Autowired
    private BankCardRepository bankCardRepository;
    //查询工厂
    private JPAQueryFactory queryFactory;
    @Autowired
    private Provider<EntityManager> entityManager;
    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    @Autowired
    UserSessionManager userSessionManager;

    public Result findBankByUserAndIsDefault(Long userId) {
        QBankCard qBankCard = QBankCard.bankCard;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qBankCard.isDefault.eq(1));
        if (!Objects.isNull(userId)) {
            builder.and(qBankCard.fUserId.eq(userId));
        }
        BankCard bankCard = queryFactory.select(
                Projections.bean(
                        BankCard.class,
                        qBankCard.name,
                        qBankCard.isDefault,
                        qBankCard.bankName,
                        qBankCard.code
                )
        ).from(qBankCard).where(builder).fetchFirst();
        return Result.ok(bankCard);
    }

    public QueryResults<BankCard> pageBankCard(String bankType, String code, String name,
                                               String bankName, Integer isDefault, String remark, int pageNum, int pageSize) {
        QBankCard qBankCard = QBankCard.bankCard;
        BooleanBuilder builder = new BooleanBuilder();
        if (StringUtils.isNotEmpty(bankType)) {
            builder.and(qBankCard.bankType.eq(bankType));
        }
        if (!Objects.isNull(code)) {
            builder.and(qBankCard.code.eq(code));
        }
        if (!Objects.isNull(name)) {
            builder.and(qBankCard.name.eq(name));
        }
        if (!Objects.isNull(bankName)) {
            builder.and(qBankCard.bankName.eq(bankName));
        }
        if (!Objects.isNull(isDefault)) {
            builder.and(qBankCard.isDefault.eq(isDefault));
        }
        return queryFactory.select(
                        Projections.bean(
                                BankCard.class,
                                qBankCard.name,
                                qBankCard.isDefault,
                                qBankCard.id,
                                qBankCard.bankType,
                                qBankCard.bankName,
                                qBankCard.code
                        )
                ).from(qBankCard)
                .where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();
    }


    public QueryResults<BankCard> pageBankCardByUser(Long userId,String bankType,String code,String name,
                                                       String bankName,Integer isDefault,String remark, int pageNum, int pageSize) {
        userId = this.userSessionManager.getUserId();
        QBankCard qBankCard = QBankCard.bankCard;
        BooleanBuilder builder = new BooleanBuilder();
        if (StringUtils.isNotEmpty(bankType)) {
            builder.and(qBankCard.bankType.eq(bankType));
        }
        if (!Objects.isNull(code)) {
            builder.and(qBankCard.code.eq(code));
        }
        if (!Objects.isNull(name)) {
            builder.and(qBankCard.name.eq(name));
        }
        if (!Objects.isNull(bankName)) {
            builder.and(qBankCard.bankName.eq(bankName));
        }
        if (!Objects.isNull(isDefault)) {
            builder.and(qBankCard.isDefault.eq(isDefault));
        }
        if (!Objects.isNull(userId)) {
            builder.and(qBankCard.fUserId.eq(userId));
        }
        return queryFactory.select(
                        Projections.bean(
                                BankCard.class,
                                qBankCard.name,
                                qBankCard.isDefault,
                                qBankCard.id,
                                qBankCard.bankType,
                                qBankCard.bankName,
                                qBankCard.code
                        )
                ).from(qBankCard)
                .where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();
    }

    @Transactional
    public Result saveBankCard(Long id,String bankType,String code,String name,String bankName,
                                             Integer isDefault,String remark) {
        Long userId = this.userSessionManager.getUserId();
        BankCard defaultBankcard = this.bankCardRepository.findOneByUserIdAndIsDefault(userId, Integer.valueOf(1));
        if (1 == isDefault && null != defaultBankcard) {
            defaultBankcard.setIsDefault(Integer.valueOf(0));
            this.bankCardRepository.saveAndFlush(defaultBankcard);
        }
        boolean value = CheckBankCard.checkBankCard(code);
        if (!value) {
            return Result.failed(2001,"卡号保存失败！该卡无效或者不支持该类银行卡，请从新输入");
        }
        BankCard savedBankCard = this.bankCardRepository.findOneByCode(code);
        if (null != savedBankCard && (null == id || !savedBankCard.getId().equals(id))) {
            return Result.failed(2002,"该银行卡已被使用");
        }
        if (null != id) {
            BankCard bankCard = this.bankCardRepository.findById(id).get();
            bankCard.setfUserId(userId);
            bankCard.setCode(code);
            bankCard.setName(name);
            bankCard.setBankName(bankName);
            bankCard.setBankType(bankType);
            if (null == defaultBankcard) {
                bankCard.setIsDefault(Integer.valueOf(1));
            } else {
                bankCard.setIsDefault(isDefault);
            }
            this.bankCardRepository.saveAndFlush(bankCard);
        }else {
            BankCard bankCard = new BankCard();
            bankCard.setfUserId(userId);
            bankCard.setCode(code);
            bankCard.setName(name);
            bankCard.setBankName(bankName);
            bankCard.setBankType(bankType);
            if (null == defaultBankcard) {
                bankCard.setIsDefault(Integer.valueOf(1));
            } else {
                bankCard.setIsDefault(isDefault);
            }
            this.bankCardRepository.save(bankCard);
        }
        return Result.ok();
    }


    public BankCard findBankByIsDefault() {
        BankCard bankcard = this.bankCardRepository.findOneByUserIdAndIsDefault(this.userSessionManager.getUserId(), Integer.valueOf(1));
        return bankcard;
    }
    public List<BankCard> findBankByUser(Long userId) {
        List<BankCard> bankcard = this.bankCardRepository.findByUserId(userId);
        return bankcard;
    }

    @Transactional
    public void setDefault(Long userId,Long cardId) {
        BankCard CustomaryCard = this.bankCardRepository.findOneByUserIdAndIsDefault(userId, Integer.valueOf(1));
        if (null != CustomaryCard) {
            CustomaryCard.setIsDefault(Integer.valueOf(0));
            this.bankCardRepository.saveAndFlush(CustomaryCard);
        }
        BankCard nowCard = this.bankCardRepository.findById(cardId).get();
        nowCard.setIsDefault(Integer.valueOf(1));
        this.bankCardRepository.save(nowCard);
    }


    @Transactional
    public void deleteBankcard(Long bankCardId) {
        Long userId = this.userSessionManager.getUserId();
        BankCard bankCard = this.bankCardRepository.findById(bankCardId).get();
        bankCard.setRemoved(Integer.valueOf(1));
        this.bankCardRepository.saveAndFlush(bankCard);
        if (null != bankCard && 1 == bankCard.getIsDefault().intValue()) {
            List<BankCard> bankcardList = this.bankCardRepository.findByUserId(userId);
            if (bankcardList.size() > 0) {
                BankCard bankcard1 = this.bankCardRepository.findById((bankcardList.get(0)).getId()).get();
                bankcard1.setIsDefault(Integer.valueOf(1));
                this.bankCardRepository.saveAndFlush(bankcard1);
            }
        }
    }

    public BankCard findBankByBankCardId(Long bankcardId) {
        return this.bankCardRepository.findById(bankcardId).get();
    }

}
